package com.example.config;

import java.util.Objects;

import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.stereotype.Component;

import com.example.enums.BaseEnum;

/**
 * 枚举类型转换工厂：反序列化时，将String类型的值转换成对应的枚举
 * 
 * @ClassName: StringToEnumFactory
 * @Description: (这里用一句话描述这个类的作用)
 * @author liuwj3
 * @date 2019年2月15日 上午10:19:38
 *
 */
// ConverterFactory<S, R>：S代表前端输入的源值（不能是Object），R代表要转换成的目标值
@Component
public class StringToEnumFactory implements ConverterFactory<String, BaseEnum<Enum<?>, Object>> {

	@Override
	public <T extends BaseEnum<Enum<?>, Object>> Converter<String, T> getConverter(Class<T> targetType) {
		if (!targetType.isEnum()) {
			throw new UnsupportedOperationException("只支持转换到枚举类型！");
		}
		// 返回自定义属性转换器
		return new StringToEnumConvert<T>(targetType);
	}

	// 内部类实现自定义属性转换器
	private class StringToEnumConvert<T extends BaseEnum<Enum<?>, Object>> implements Converter<String, T> {

		private final Class<T> enumType;

		public StringToEnumConvert(Class<T> enumType) {
			this.enumType = enumType;
		}

		@Override
		public T convert(String source) {
			if (source.toString().length() == 0) {
				// It's an empty enum identifier: reset the enum value to null.
				return null;
			}
			T[] enumConstants = enumType.getEnumConstants();
			for (T t : enumConstants) {
				if (Objects.equals(t.getValue().toString(), source)) {
					return t;
				}
			}
			return null;
		}
	}

}
